package cn.ultrarisk.sprinx.mybatis.query;

import cn.ultrarisk.sprinx.util.Utilities;

import java.util.ArrayList;
import java.util.List;

/**
 * Criteria
 *
 * @author sevendlong(lin23871@163.com)
 * @date 2014/9/30
 * @since V1.0
 */
public class Criteria {
    private String key;
    private Opt opt;
    private Object value;

    private Query.Logical subLogical = Query.Logical.AND;
    private List<Criteria> subCriterias;

    public Criteria(String key, Opt opt, Object value) {
        this.key = key;
        this.opt = opt;
        this.value = value;
    }

    public Criteria(Criteria... subCriterias) {
        this(Query.Logical.AND, subCriterias);
    }

    public Criteria(Query.Logical subLogical, Criteria... subCriterias) {
        this.subLogical = subLogical;
        for (Criteria subCriteria: subCriterias) {
            this.addSubCriteria(subCriteria);
        }
    }

    public Criteria(Query.Logical subLogical, List<Criteria> subCriterias) {
        this.subLogical = subLogical;
        for (Criteria subCriteria: subCriterias) {
            this.addSubCriteria(subCriteria);
        }
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public Opt getOpt() {
        return opt;
    }

    public void setOpt(Opt opt) {
        this.opt = opt;
    }

    public String getOptValue() {
        return this.opt.value();
    }

    public String getOptAlias() {
        return this.opt.alias();
    }

    public Object getValue() {
        return value;
    }

    public void setValue(Object value) {
        this.value = value;
    }

    public Query.Logical getSubLogical() {
        return subLogical;
    }

    public void setSubLogical(Query.Logical subLogical) {
        this.subLogical = subLogical;
    }

    public List<Criteria> getSubCriterias() {
        return subCriterias;
    }

    public void setSubCriterias(List<Criteria> subCriterias) {
        this.subCriterias = subCriterias;
    }

    public void addSubCriteria(Criteria subCriteria) {
        if (this.subCriterias == null) {
            this.subCriterias = new ArrayList<Criteria>();
        }
        this.subCriterias.add(subCriteria);
    }

    public Criteria copy() {
        Criteria criteria = new Criteria(this.key, this.opt, this.value);
        if (Utilities.isNotEmpty(this.subCriterias)) {
            for (Criteria subCriteria : this.subCriterias) {
                criteria.addSubCriteria(subCriteria);
            }
        }
        return criteria;
    }

    /**
     * 查询运算符
     *
     * @author sevendlong(lin23871@163.com)
     * @date 2014/9/30
     * @since V1.0
     */
    public static enum Opt {
        EQ("=", "EQ"),
        NE("!=", "NE"),
        GT(">", "GT"),
        GTE(">=", "GTE"),
        LT("<", "LT"),
        LTE("<=", "LTE"),
        LIKE("LIKE", "LIKE"),
        LIKE_PREFIX("LIKE_PREFIX", "LIKE_PREFIX"),
        LIKE_SUFFIX("LIKE_SUFFIX", "LIKE_SUFFIX"),
        LIKE_FULL("LIKE_FULL", "LIKE_FULL"),
        IN("IN", "IN"),
        NIN("NOT IN", "NIN");

        private String value;
        private String alias;
        Opt(String value, String alias) {
            this.value = value;
            this.alias = alias;
        }

        public String value() {
            return this.value;
        }

        public String alias() {
            return this.alias;
        }
    }
}
